import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.nio.ByteOrder;
import java.nio.DoubleBuffer;
import java.nio.IntBuffer;
import org.lwjgl.*;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.*;
import org.lwjgl.util.Color;
import org.lwjgl.util.glu.GLU;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL20.*;

public class GLTestingAgainErik
{
	static final double steplength = 0.01;
	static boolean freeCamera = true;
	static double speedBoost = .5;

	static double rotateSpeed =1;
	static double movementSpeed = .05; 
	static boolean gridEnabled = false;
	static boolean MOVE = false;
	static double[] currentTrackLocation = { 0, 0, 0 };
	static double[] currentTrackDirection = { 0, 0 };
	static Garbage2 theCart = new Garbage2(0, 6, 3, 5, currentTrackDirection.clone());
	static int realPathIterator = 0;
	static float shit, shack;
	static float[] red = { 1, 0, 0 };
	static float[] blue = { 0, 0, 1 };
	static float[] green = { 0, 1, 0 };
	static float[] yellow = { 1, 1, 0 };
	static float[] white = { 1, 1, 1 };
	static ByteBuffer shitState = ByteBuffer.allocateDirect(128);
	static DoubleBuffer lastState = shitState.asDoubleBuffer();
	static float n = 0;
	static double piover180 = Math.PI / 180.;

	static double[] sineTable = buildSineTable();
	static double[] cosineTable = buildCosineTable();

	static double scalex, scaley, X, Y, Z;
	static float pitch, roll;
	static float yaw = 180;

	static double[] zpos = { 0, 0, 1 };
	static double[] zneg = { 0, 0, -1 };
	static double[] xpos = { 1, 0, 0 };
	static double[] xneg = { -1, 0, 0 };
	
	static boolean keyPressed = false;

	
	static ArrayList<double[]> theRealPathDirectionVectors = new ArrayList<double[]>();
	
	static ArrayList<double[]> theRealPath = buildPath();



	public static void main(String[] args)
	{

		try
		{

			Display.setDisplayModeAndFullscreen(new DisplayMode(1280, 1024));
			Display.create();

		} catch (Exception e)
		{
		}

		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glFrustum(-1.0, 1.0, -1.0, 1.0, 1.2, 2000.0);

		glMatrixMode(GL_MODELVIEW);
		glViewport(0, 0, 1280, 1024);

		while (!Display.isCloseRequested())
		{

			try
			{
				display();
			} catch (Exception e)
			{
				e.printStackTrace();
				System.exit(1);
			}

			// You see this line?
			Display.update();
			// Don't you DARE remove it!
			// Doing so will lock up the entire machine!
		}
		Display.destroy();

	}

	static ArrayList<double[]> buildPath()
	{
		ArrayList<double[]> path = new ArrayList<double[]>();

		// path.addAll(buildStraightPiece(1, new double[] { -5, 0, 0 }, new
		// double[] { 0, 0, 1 }));

		path.addAll(buildAnyPiece(4, currentTrackLocation, 0, 0));

		return path;
	}

	static void forward()
	{
		theRealPath.addAll(buildAnyPiece(1, currentTrackLocation, 0, 0));
	}

	static void left()
	{
		theRealPath.addAll(buildAnyPiece(1, currentTrackLocation, 0, 90));
	}

	static void right()
	{
		theRealPath.addAll(buildAnyPiece(1, currentTrackLocation, 0, -90));
	}

	static void up()
	{
		theRealPath.addAll(buildAnyPiece(1, currentTrackLocation, 90, 0));
	}

	static void down()
	{
		theRealPath.addAll(buildAnyPiece(1, currentTrackLocation, -90, 0));
	}

	static void drawPath(ArrayList<double[]> path, float[] color)
	{	
		double pathWidth = .1;
		double pathThickness = .1;
		glColor3f(color[0], color[1], color[2]);
		//glBegin(GL_QUADS);
		for(int i =1; i< path.size(); i++)
		{
			glColor3f(color[0], color[1], color[2]);

			glBegin(GL_QUADS);
			
			double[] firstpoint = path.get(i-1);
			double[] secondpoint = path.get(i);
			double[] direction = theRealPathDirectionVectors.get(i-1);
			//glVertex3d(firstpoint[0]+pathWidth*direction[2], firstpoint[1], firstpoint[2]+pathWidth*direction[0]);
			//glVertex3d(secondpoint[0]+pathWidth*direction[2], secondpoint[1], secondpoint[2]+pathWidth*direction[0]);
			//glVertex3d(secondpoint[0]-pathWidth*direction[2], secondpoint[1], secondpoint[2]-pathWidth*direction[0]);
			//glVertex3d(firstpoint[0]-pathWidth*direction[2], firstpoint[1], firstpoint[2]-pathWidth*direction[0]);
			double zToXRatio = 0;
			double[] widthDir = {0, 0};
			if (direction[0] != 0 ) {
				zToXRatio = (-1.0) * direction[2] / direction[0];
				widthDir[0] = (-1.0) * zToXRatio;
				widthDir[1] = -1.0;
				
				double normalize = Math.sqrt(Math.pow(widthDir[0], 2) + 1);
				
				widthDir[0] = widthDir[0] / normalize;
				widthDir[1] = widthDir[1] / normalize;
			} else {
				zToXRatio = -1;
				widthDir[0] = -1;
			}
			
			
			
			glVertex3d(firstpoint[0]+pathWidth*widthDir[0], firstpoint[1], firstpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]+pathWidth*widthDir[0], secondpoint[1], secondpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]-pathWidth*widthDir[0], secondpoint[1], secondpoint[2]-pathWidth*widthDir[1]);
			glVertex3d(firstpoint[0]-pathWidth*widthDir[0], firstpoint[1], firstpoint[2]-pathWidth*widthDir[1]);

			glVertex3d(firstpoint[0]+pathWidth*widthDir[0], firstpoint[1] - pathThickness, firstpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]+pathWidth*widthDir[0], secondpoint[1] - pathThickness, secondpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]-pathWidth*widthDir[0], secondpoint[1] - pathThickness, secondpoint[2]-pathWidth*widthDir[1]);
			glVertex3d(firstpoint[0]-pathWidth*widthDir[0], firstpoint[1] - pathThickness, firstpoint[2]-pathWidth*widthDir[1]);

			glVertex3d(firstpoint[0]+pathWidth*widthDir[0], firstpoint[1], firstpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]+pathWidth*widthDir[0], secondpoint[1], secondpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]+pathWidth*widthDir[0], secondpoint[1] - pathThickness, secondpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(firstpoint[0]+pathWidth*widthDir[0], firstpoint[1] - pathThickness, firstpoint[2]+pathWidth*widthDir[1]);

			glVertex3d(firstpoint[0]-pathWidth*widthDir[0], firstpoint[1]-pathThickness, firstpoint[2]-pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]-pathWidth*widthDir[0], secondpoint[1]-pathThickness, secondpoint[2]-pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]-pathWidth*widthDir[0], secondpoint[1], secondpoint[2]-pathWidth*widthDir[1]);
			glVertex3d(firstpoint[0]-pathWidth*widthDir[0], firstpoint[1], firstpoint[2]-pathWidth*widthDir[1]);
			
			
			glEnd();
			
			glColor3f(1f, 1f, 1f);
			glBegin(GL_LINES);
			
			glVertex3d(firstpoint[0]+pathWidth*widthDir[0], firstpoint[1], firstpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]+pathWidth*widthDir[0], secondpoint[1], secondpoint[2]+pathWidth*widthDir[1]);
			
			glVertex3d(secondpoint[0]+pathWidth*widthDir[0], secondpoint[1], secondpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(secondpoint[0]-pathWidth*widthDir[0], secondpoint[1], secondpoint[2]-pathWidth*widthDir[1]);
			
			glVertex3d(secondpoint[0]-pathWidth*widthDir[0], secondpoint[1], secondpoint[2]-pathWidth*widthDir[1]);
			glVertex3d(firstpoint[0]-pathWidth*widthDir[0], firstpoint[1], firstpoint[2]-pathWidth*widthDir[1]);
			
			glVertex3d(firstpoint[0]+pathWidth*widthDir[0], firstpoint[1], firstpoint[2]+pathWidth*widthDir[1]);
			glVertex3d(firstpoint[0]-pathWidth*widthDir[0], firstpoint[1], firstpoint[2]-pathWidth*widthDir[1]);

			glEnd();
			//dummy comment
			/*glColor3f(1f, 1f, 1f);
			glBegin(GL_LINES);
			glVertex3d(firstpoint[0]+pathWidth*direction[2], firstpoint[1], firstpoint[2]+pathWidth*direction[0]);
			glVertex3d(secondpoint[0]+pathWidth*direction[2], secondpoint[1], secondpoint[2]+pathWidth*direction[0]);
			glEnd();
			glBegin(GL_LINES);
			glVertex3d(secondpoint[0]+pathWidth*direction[2], secondpoint[1], secondpoint[2]+pathWidth*direction[0]);
			glVertex3d(secondpoint[0]-pathWidth*direction[2], secondpoint[1], secondpoint[2]-pathWidth*direction[0]);
			glEnd();
			glBegin(GL_LINES);
			glVertex3d(secondpoint[0]-pathWidth*direction[2], secondpoint[1], secondpoint[2]-pathWidth*direction[0]);
			glVertex3d(firstpoint[0]-pathWidth*direction[2], firstpoint[1], firstpoint[2]-pathWidth*direction[0]);
			glEnd();
			glBegin(GL_LINES);
			glVertex3d(firstpoint[0]+pathWidth*direction[2], firstpoint[1], firstpoint[2]+pathWidth*direction[0]);
			glVertex3d(firstpoint[0]-pathWidth*direction[2], firstpoint[1], firstpoint[2]-pathWidth*direction[0]);
			glEnd();*/
			
		}
		glColor3f(0.0f, 0.0f, 0.0f);
		for(int i =1; i< path.size(); i++)
		{
			glBegin(GL_LINES);
			
			double[] firstpoint = path.get(i-1);
			double[] secondpoint = path.get(i);
			double[] direction = theRealPathDirectionVectors.get(i-1);
			glVertex3d(firstpoint[0], firstpoint[1], firstpoint[2]);
			glVertex3d(secondpoint[0], secondpoint[1], secondpoint[2]);
			
			glEnd();
			
		}
		
//		for (double[] p : path)
//		{
////////glVertex3d(p[0], p[1], p[2]);
//		}
		
		//glEnd();
	}

	static void display() throws InterruptedException
	{
		glMatrixMode(GL_MODELVIEW);
		glClear(GL_COLOR_BUFFER_BIT);
		glLoadIdentity();

		if (Mouse.isButtonDown(0))
		{
			X = (Mouse.getX() - Display.getDisplayMode().getWidth() / 2.0) / 100.0;
			Y = (Mouse.getY() - Display.getDisplayMode().getWidth() / 2.0) / 100.0;

		}
		// Does not handle roll!
		if (Keyboard.isKeyDown(Keyboard.KEY_UP))
		{

			Z += movementSpeed * Math.cos(piover180 * yaw);
			Y += movementSpeed * Math.sin(piover180 * pitch);
			X -= movementSpeed * Math.sin(piover180 * yaw);

		}
		// Does not handle roll!
		if (Keyboard.isKeyDown(Keyboard.KEY_DOWN))
		{
			Z -= movementSpeed * Math.cos(piover180 * yaw);
			Y -= movementSpeed * Math.sin(piover180 * pitch);
			X += movementSpeed * Math.sin(piover180 * yaw);

		}
		if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
		{
			yaw+=rotateSpeed;
			// System.out.println(yaw+"y");
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_LEFT))
		{
			yaw-=rotateSpeed;
			// System.out.println(yaw+"y");
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_1))
		{
			pitch+=rotateSpeed;
			// System.out.println(pitch+"p");
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_4))
		{
			pitch-=rotateSpeed;
			// System.out.println(pitch+"p");
		}
		Keyboard.enableRepeatEvents(false);
		if (Keyboard.isKeyDown(Keyboard.KEY_SPACE))
		{
			if (keyPressed == false){forward();}
			keyPressed = true;
		}
		else if (Keyboard.isKeyDown(Keyboard.KEY_W))
		{
			if (keyPressed == false){up();}
			keyPressed = true;
		}
		else if (Keyboard.isKeyDown(Keyboard.KEY_S))
		{
			if (keyPressed == false){down();}
			keyPressed = true;
		}
		else if (Keyboard.isKeyDown(Keyboard.KEY_A))
		{
			if (keyPressed == false){left();}
			keyPressed = true;
		}
		else if (Keyboard.isKeyDown(Keyboard.KEY_D))
		{
			if (keyPressed == false) {
				right();
			}
			keyPressed = true;
		} else {
			keyPressed = false;
		}
		
		if (Keyboard.isKeyDown(Keyboard.KEY_G))
		{
			gridEnabled = !gridEnabled;
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_M)){
			MOVE = !MOVE;
		}
		if (Keyboard.isKeyDown(Keyboard.KEY_ADD))
		{
			theCart.g -= 1;
			System.out.println("GRAVITY = -"+theCart.g);
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_SUBTRACT))
		{
			theCart.g+=1;
			System.out.println("GRAVITY = "+theCart.g);
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_I))
		{
			movementSpeed+=.1;
			System.out.println("MOVEMENT SPEED = "+movementSpeed);
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_U))
		{
			movementSpeed-=.1;
			System.out.println("MOVEMENT SPEED = "+movementSpeed);
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_C))
		{
			rotateSpeed+=.1;
			System.out.println("ROTATION SPEED = "+rotateSpeed);
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_X))
		{
			rotateSpeed-=.1;
			System.out.println("ROTATION SPEED = "+rotateSpeed);
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_B))
		{
			theCart.speed /=1.15;
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_NUMPAD1))
		{
			theCart.speed += speedBoost;
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_NUMPAD2))
		{
			theCart.speed -= speedBoost;
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_NUMPAD7))
		{
			speedBoost += .01;
			System.out.println("SPEEDBOOST = "+ speedBoost);
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_NUMPAD8))
		{
			speedBoost -= .01;
			System.out.println("SPEEDBOOST = "+speedBoost);
		}
		if(Keyboard.isKeyDown(Keyboard.KEY_F))
		{
			freeCamera = !freeCamera;
		}
		
		
		
		
		
		// drawCrosshair(white);
		glRotatef(pitch, 1, 0, 0);
		glRotatef(yaw, 0, 1, 0);
		glRotatef(roll, 0, 0, 1);

		if(freeCamera)
		{
			glTranslated(X,Y,Z);
		}
		else
		{
			glTranslated(-theCart.location[0], -(theCart.location[1] +1), -theCart.location[2]);
		}
		// This is important otherwise your motion is too fast.
		Thread.sleep(10);

		drawCube(0, 0, -4, red);
		drawCube(4, 0, 0, blue);
		drawCube(0, 0, 4, green);
		drawCube(-4, 0, 0, yellow);


		drawCube(0, shit, 0, white);



		drawSineWave();
		drawCosineWave();
		drawPath(theRealPath, green);

		if (gridEnabled)
			drawGrid(300, -5, 300, yellow, 7, theCart.location);

		if(MOVE){
			if(realPathIterator <0)
				realPathIterator = theRealPath.size()-1;
			theCart.location = theRealPath.get(realPathIterator);
			drawCubev(theCart.location, red, 1);
			

			realPathIterator += theCart.updateSpeed(realPathIterator, theRealPathDirectionVectors);

			if (realPathIterator >= theRealPath.size())
				realPathIterator = 0;
		}

		glFlush();
	}

	static void drawCrosshair(float color[])
	{
		glColor3f(color[0], color[1], color[2]);
		glBegin(GL_LINE_STRIP);
		glVertex3f(0f, 0f, -1.5f);

		glVertex3f(1f, 0f, -1.5f);
		glColor3f(0, 1, 0);
		glVertex3f(-1f, 0f, -1.5f);
		// glVertex3f(0f,0,-2);
		glEnd();
	}

	static void drawSineWave()
	{

		glColor3f(0.0f, 0f, 1.0f);
		glBegin(GL_LINE_STRIP);
		for (int i = 0; i < 36000; i += 1)
		{
			glVertex3d(i / 3600.0, sineTable[i], 0);

		}
		glEnd();
	}

	static void drawCosineWave()
	{
		glColor3f(0.0f, .5f, 0);
		glBegin(GL_LINE_STRIP);
		for (int i = 0; i < 36000; i += 1)
		{
			glVertex3d(i / 3600.0, cosineTable[i], 0);

		}
		glEnd();
	}

	static void drawGrid(int x, int y, int z, float[] color, double resolution, double[] loc)
	{
		glColor3f(color[0], color[1], color[2]);
		for (double i = x * -1; i < x; i += resolution)
		{
			glBegin(GL_LINE_STRIP);
			glVertex3d(i+loc[0], y+loc[1], -z+loc[2]);
			glVertex3d(i+loc[0], y+loc[1], z+loc[2]);
			glEnd();
		}
		for (double i = z * -1; i < z; i += resolution)
		{
			glBegin(GL_LINE_STRIP);
			glVertex3d(-x+loc[0], y+loc[1], i+loc[2]);
			glVertex3d(x+loc[0], y+loc[1], i+loc[2]);
			glEnd();
		}
	}

	// This will draw a wireframe cube of a fixed size at the location (x,y,z)
	// with color {red, green, blue}
	static void drawCubed(double x, double y, double z, float[] color)
	{
		glColor3f(color[0], color[1], color[2]);
		glBegin(GL_LINE_STRIP);
		glVertex3d(0 + x, 0 + y, 0 + z);
		glVertex3d(1 + x, 0 + y, 0 + z);
		glVertex3d(1 + x, 1 + y, 0 + z);
		glVertex3d(0 + x, 1 + y, 0 + z);

		glVertex3d(0 + x, 1 + y, -1 + z);
		glVertex3d(0 + x, 0 + y, -1 + z);
		glVertex3d(1 + x, 0 + y, -1 + z);
		glVertex3d(1 + x, 1 + y, -1 + z);
		glVertex3d(0 + x, 1 + y, -1 + z);

		glVertex3d(0 + x, 1 + y, 0 + z);
		glVertex3d(0 + x, 0 + y, 0 + z);
		glVertex3d(0 + x, 0 + y, -1 + z);
		glVertex3d(1 + x, 0 + y, -1 + z);
		glVertex3d(1 + x, 0 + y, 0 + z);
		glVertex3d(1 + x, 1 + y, 0 + z);
		glVertex3d(1 + x, 1 + y, -1 + z);
		glEnd();
	}

	static double sine(double angle)
	{
		if (angle < 0)
		{
			return sineTable[(int) (((angle * -1) % 360) * 100)] * -1;
		} else
		{
			return sineTable[(int) ((angle % 360) * 100)];
		}
	}

	static double cosine(double angle)
	{
		return cosineTable[Math.abs((int) ((angle % 360) * 100))];
	}


	static ArrayList<double[]> buildAnyPiece(double l, double[] loc, double pitch, double yaw)
	{
		
		double[] curDir = currentTrackDirection;
		double[] curLoc = loc;
		ArrayList<double[]> piece = new ArrayList<double[]>();

		int steps = (int) (100 * l);
		double angular_pitch_step = pitch / steps;
		double angular_yaw_step = yaw / steps;

		int i;
		for (i = 0; i < steps; i++)
		{	
			piece.add(curLoc.clone());

			curDir[0] += angular_pitch_step; // THETA
			curDir[1] += angular_yaw_step; // PHI
		
			double deltax = steplength * cosine(curDir[0]) * sine(curDir[1]);
			double deltay = steplength * sine(curDir[0]);
			double deltaz = steplength * cosine(curDir[0]) * cosine(curDir[1]);
			theRealPathDirectionVectors.add(new double[]{deltax,deltay,deltaz});
			
			curLoc[0] += deltax;
			curLoc[1] += deltay;
			curLoc[2] += deltaz;
		}

		currentTrackLocation = curLoc;
		currentTrackDirection = curDir;

		return piece;
	}

	static void drawCube(float x, float y, float z, float[] color)
	{
		glColor3f(color[0], color[1], color[2]);
		glBegin(GL_LINE_STRIP);
		glVertex3f(0 + x, 0 + y, 0 + z);
		glVertex3f(1 + x, 0 + y, 0 + z);
		glVertex3f(1 + x, 1 + y, 0 + z);
		glVertex3f(0 + x, 1 + y, 0 + z);

		glVertex3f(0 + x, 1 + y, -1 + z);
		glVertex3f(0 + x, 0 + y, -1 + z);
		glVertex3f(1 + x, 0 + y, -1 + z);
		glVertex3f(1 + x, 1 + y, -1 + z);
		glVertex3f(0 + x, 1 + y, -1 + z);

		glVertex3f(0 + x, 1 + y, 0 + z);
		glVertex3f(0 + x, 0 + y, 0 + z);
		glVertex3f(0 + x, 0 + y, -1 + z);
		glVertex3f(1 + x, 0 + y, -1 + z);
		glVertex3f(1 + x, 0 + y, 0 + z);
		glVertex3f(1 + x, 1 + y, 0 + z);
		glVertex3f(1 + x, 1 + y, -1 + z);
		glEnd();

	}

	static void drawCubev(double[] xyz, float[] color, double scale)
	{
		glColor3f(color[0], color[1], color[2]);
		glBegin(GL_LINE_STRIP);
		glVertex3d(0 + xyz[0], 0 + xyz[1], 0 + xyz[2]);
		glVertex3d(scale + xyz[0], 0 + xyz[1], 0 + xyz[2]);
		glVertex3d(scale + xyz[0], scale + xyz[1], 0 + xyz[2]);
		glVertex3d(0 + xyz[0], scale + xyz[1], 0 + xyz[2]);

		glVertex3d(0 + xyz[0], scale + xyz[1], -scale + xyz[2]);
		glVertex3d(0 + xyz[0], 0 + xyz[1], -scale + xyz[2]);
		glVertex3d(scale + xyz[0], 0 + xyz[1], -scale + xyz[2]);
		glVertex3d(scale + xyz[0], scale + xyz[1], -scale + xyz[2]);
		glVertex3d(0 + xyz[0], scale + xyz[1], -scale + xyz[2]);

		glVertex3d(0 + xyz[0], scale + xyz[1], 0 + xyz[2]);
		glVertex3d(0 + xyz[0], 0 + xyz[1], 0 + xyz[2]);
		glVertex3d(0 + xyz[0], 0 + xyz[1], -scale + xyz[2]);
		glVertex3d(scale + xyz[0], 0 + xyz[1], -scale + xyz[2]);
		glVertex3d(scale + xyz[0], 0 + xyz[1], 0 + xyz[2]);
		glVertex3d(scale + xyz[0], scale + xyz[1], 0 + xyz[2]);
		glVertex3d(scale + xyz[0], scale + xyz[1], -scale + xyz[2]);
		glEnd();

	}

	public static double[] buildSineTable()
	{
		double piover180 = (Math.PI / 180.0);
		double[] Table = new double[36001];
		int intdegree = 0;
		for (double degree = 0; degree < 360; degree += 0.01)
		{

			Table[intdegree] = Math.sin(piover180 * degree);

			intdegree++;
		}
		return Table;
	}

	public static double[] buildCosineTable()
	{
		double piover180 = (Math.PI / 180.0);
		double[] cosineTable = new double[36001];
		int intdegree = 0;
		for (double degree = 0; degree < 360; degree += 0.01)
		{

			cosineTable[intdegree] = Math.cos(piover180 * degree);
			intdegree++;

		}
		return cosineTable;
	}

}

class Garbage2
{
	double steplength = GLTestingAgain.steplength;
	double g = -80;
	double speed, acceleration;
	double[] location = new double[3];
	double[] direction;
	double height;

	public Garbage2(double xx, double yy, double zz, double s, double[] dir)
	{
		location[0] = xx;
		location[1] = yy;
		location[2] = zz;
		speed = s;
		direction = dir;
		height = yy;
	}

	public double updateSpeed(int index, ArrayList<double[]> list)
	{
		acceleration =  list.get(index)[1] *g;
		speed += acceleration;	

		return speed;
	}

}